﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.EncryptedData
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Security.Cryptography;
using System.Xml;

namespace Microsoft.InfoCards
{
  internal class EncryptedData
  {
    private string m_type;
    private EncryptedData.EncryptionMethodElement m_encryptionMethod;
    private EncryptedData.CipherData m_cipherData;
    private SecurityKeyIdentifier m_keyIdentifier;
    private SecurityTokenSerializer m_tokenSerializer;

    public EncryptedData()
    {
      this.m_cipherData = new EncryptedData.CipherData();
      this.m_encryptionMethod = new EncryptedData.EncryptionMethodElement();
    }

    public string EncryptionMethod
    {
      set
      {
        this.m_encryptionMethod.algorithm = value;
      }
    }

    public SecurityKeyIdentifier KeyIdentifier
    {
      set
      {
        this.m_keyIdentifier = value;
      }
    }

    public string Type
    {
      set
      {
        this.m_type = value;
      }
    }

    public SecurityTokenSerializer TokenSerializer
    {
      set
      {
        this.m_tokenSerializer = value;
      }
    }

    public void SetUpEncryption(
      SymmetricAlgorithm algorithm,
      byte[] buffer,
      int offset,
      int length)
    {
      InfoCardTrace.ThrowInvalidArgumentConditional(null == algorithm, nameof (algorithm));
      byte[] iv;
      byte[] cipherText;
      this.GenerateIVAndEncrypt(algorithm, buffer, offset, length, out iv, out cipherText);
      this.m_cipherData.SetCipherValueFragments(iv, cipherText);
    }

    public void WriteTo(XmlWriter writer)
    {
      writer.WriteStartElement("enc", nameof (EncryptedData), "http://www.w3.org/2001/04/xmlenc#");
      if (!string.IsNullOrEmpty(this.m_type))
        writer.WriteAttributeString("Type", (string) null, this.m_type);
      if (!string.IsNullOrEmpty(this.m_encryptionMethod.algorithm))
        this.m_encryptionMethod.WriteTo(writer);
      if (this.m_keyIdentifier != null)
        this.m_tokenSerializer.WriteKeyIdentifier((XmlWriter) XmlDictionaryWriter.CreateDictionaryWriter(writer), this.m_keyIdentifier);
      this.m_cipherData.WriteTo(writer);
      writer.WriteEndElement();
    }

    private void GenerateIVAndEncrypt(
      SymmetricAlgorithm algorithm,
      byte[] plainText,
      int offset,
      int length,
      out byte[] iv,
      out byte[] cipherText)
    {
      RandomNumberGenerator randomNumberGenerator = (RandomNumberGenerator) new RNGCryptoServiceProvider();
      int length1 = algorithm.BlockSize / 8;
      iv = new byte[length1];
      randomNumberGenerator.GetBytes(iv);
      algorithm.Padding = PaddingMode.PKCS7;
      algorithm.Mode = CipherMode.CBC;
      using (ICryptoTransform encryptor = algorithm.CreateEncryptor(algorithm.Key, iv))
        cipherText = encryptor.TransformFinalBlock(plainText, offset, length);
    }

    private struct CipherData
    {
      private byte[] m_iv;
      private byte[] m_cipherText;

      public byte[] CipherValue
      {
        get
        {
          return this.m_cipherText;
        }
      }

      public void SetCipherValueFragments(byte[] iv, byte[] cipherText)
      {
        this.m_iv = iv;
        this.m_cipherText = cipherText;
      }

      public void WriteTo(XmlWriter writer)
      {
        writer.WriteStartElement("enc", nameof (CipherData), "http://www.w3.org/2001/04/xmlenc#");
        writer.WriteStartElement("enc", "CipherValue", "http://www.w3.org/2001/04/xmlenc#");
        if (this.m_iv != null)
          writer.WriteBase64(this.m_iv, 0, this.m_iv.Length);
        writer.WriteBase64(this.m_cipherText, 0, this.m_cipherText.Length);
        writer.WriteEndElement();
        writer.WriteEndElement();
      }
    }

    private struct EncryptionMethodElement
    {
      internal string algorithm;

      public void WriteTo(XmlWriter writer)
      {
        writer.WriteStartElement("enc", "EncryptionMethod", "http://www.w3.org/2001/04/xmlenc#");
        writer.WriteAttributeString("Algorithm", (string) null, this.algorithm);
        writer.WriteEndElement();
      }
    }
  }
}
